package cn.acac.yygh.hosp.service.impl;

import cn.acac.yygh.dict.DictFeignClient;
import cn.acac.yygh.enums.DictEnum;
import cn.acac.yygh.exception.MyException;
import cn.acac.yygh.hosp.config.HospitalRepository;
import cn.acac.yygh.hosp.mapper.HospitalSetMapper;
import cn.acac.yygh.hosp.service.HospitalService;
import cn.acac.yygh.hosp.service.HospitalSetService;
import cn.acac.yygh.model.hosp.Hospital;
import cn.acac.yygh.model.hosp.HospitalSet;
import cn.acac.yygh.utils.MD5;
import cn.acac.yygh.vo.hosp.HospitalQueryVo;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.management.Query;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class HospitalServiceImpl implements HospitalService {

    @Autowired
    private HospitalRepository hospitalRepository;

    @Autowired
    private HospitalSetMapper hospitalSetMapper;

    @Autowired
    public DictFeignClient dictFeignClient;


    /**
     * 向MongoDB中存储信息
     * @param map   需要存储的信息
     */
    @Override
    public void saveHospital(Map<String, Object> map) {
        // 将map转换为pojo对象
        Hospital hospital = JSONObject.parseObject(JSONObject.toJSONString(map), Hospital.class);
        // 根据hospital的hoscode判断MongoDB中是否存在此数据
        Hospital result = hospitalRepository.findByHoscode(hospital.getHoscode());
        // 判断是否为null
        if(result == null){
            // 进行添加操作
            hospital.setStatus(0);
            hospital.setCreateTime(new Date());
            hospital.setUpdateTime(new Date());
            hospital.setIsDeleted(0);
            hospitalRepository.save(hospital);
        }else {
            // 进行修改操作
            hospital.setStatus(result.getStatus());
            hospital.setCreateTime(result.getCreateTime());
            hospital.setUpdateTime(new Date());
            hospital.setIsDeleted(result.getIsDeleted());
            hospital.setId(result.getId()); // 根据id进行更新
            hospitalRepository.save(hospital);
        }
    }

    /**
     * 根据医院的编号查询医院的sign
     * @param hoscode
     * @return
     */
    @Override
    public String findSignByHoscode(Object hoscode) {
        QueryWrapper<HospitalSet> queryWrapper = new QueryWrapper<>();
        // 配置查询条件
        queryWrapper.eq("hoscode",hoscode);
        HospitalSet hospitalSet = hospitalSetMapper.selectOne(queryWrapper);
        // 进行验证
        if(hospitalSet == null){
            throw new MyException(50000,"医院信息不存在！");
        }
        return hospitalSet.getSignKey();
    }

    /**
     * 根据医院的编号查询医院的信息
     * @param hoscode
     * @return
     */
    @Override
    public Hospital findHospitalByHoscode(String hoscode,String sign) {
        // 从MongoDB中查询医院信息
        Hospital hospital = hospitalRepository.findByHoscode(hoscode);
        // 配置查询条件
        // 进行验证
        if(!StringUtils.isEmpty(hospital)){
            return hospital;
        }
        throw new MyException(50000,"医院信息不存在或秘钥不正确！");
    }

    /**
     * 将查询的第三方医院的信息返回给前端
     * @param pageNum
     * @param pageSize
     * @param hospitalQueryVo
     * @return
     */
    @Override
    public Page<Hospital> findHospitalPage(Integer pageNum, Integer pageSize, HospitalQueryVo hospitalQueryVo) {
        Hospital hospital = new Hospital();
        BeanUtils.copyProperties(hospitalQueryVo,hospital);
        //创建匹配器，即如何使用查询条件
        ExampleMatcher matcher = ExampleMatcher.matching() //构建对象
                .withMatcher("hosname",ExampleMatcher.GenericPropertyMatchers.contains()) //改变默认字符串匹配方式：模糊查询
                .withIgnoreCase(true); //改变默认大小写忽略方式：忽略大小写
        // 设置查询条件
        Example<Hospital> of = Example.of(hospital, matcher);
        // 创建分页对象
        Pageable pageable = PageRequest.of(pageNum - 1,pageSize);
        Page<Hospital> all = hospitalRepository.findAll(of, pageable);
        // 此时hospital中的省、市、区都是编号，我们需要将编号转为对应的省、市、区
        all.getContent().stream().forEach(item -> {
            // 此处调用字典服务
            this.hospitalRestructure(item);
        });
        return all;
    }

    /**
     * 根据医院的id修改医院的状态
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(String id, Integer status) {
        // 先根据id获取医院信息
        Hospital hospital = hospitalRepository.findById(id).get();
        if(hospital == null){
            throw new MyException(50000,"医院信息不存在！");
        }
        // 将状态设置进去
        hospital.setStatus(status);
        // 再次进行保存
        hospitalRepository.save(hospital);
    }

    /**
     * 根据id获取医院的详细信息
     * @param id
     * @return
     */
    @Override
    public Hospital findHospitalById(String id) {
        Hospital hospital = hospitalRepository.findById(id).get();
        // 调用cmn服务将省、市、区的编号转化为对应的文字
        this.hospitalRestructure(hospital);
        return hospital;
    }

    /**
     * 根据医院名称进行模糊查询
     * @param name
     * @return
     */
    @Override
    public List<Hospital> findHospByName(String name) {
        return hospitalRepository.findByHosnameLike(name);
    }

    /**
     * 根据医院的编号查询医院的信息
     * @param hoscode
     * @return
     */
    @Override
    public Hospital findHospByHoscode(String hoscode) {
        Hospital hospital = hospitalRepository.findByHoscode(hoscode);
        // 此时医院的等级。省市区都是编号，我们需要转换一下
        this.hospitalRestructure(hospital);
        return hospital;
    }

    private void hospitalRestructure(Hospital hospital){
        // 省编号
        String provinceCode = hospital.getProvinceCode();
        // 市编号
        String cityCode = hospital.getCityCode();
        // 区编号
        String districtCode = hospital.getDistrictCode();
        // 医院编号
        String hostype = hospital.getHostype();

        // 获取编号对应的文字
        String provinceName = dictFeignClient.findNameByValue(provinceCode);
        String cityName = dictFeignClient.findNameByValue(cityCode);
        String districtName = dictFeignClient.findNameByValue(districtCode);
        String hosInfo = dictFeignClient.findNameByValue(DictEnum.HOSTYPE.getDictCode(), hostype);
        // 保存地址
        hospital.getParam().put("address",provinceName + cityName + districtName + hospital.getAddress());
        // 保存医院信息
        hospital.getParam().put("hospInfo",hosInfo);
    }
}
